/**
 * 无论是否受权限控制的路由信息都要先确定下来, 
 * 然后根据路由权限控制接口的 name 匹配当前路由的 name 确定路由是否需要绑定注册
 */
import Vue from 'vue'
import Router from 'vue-router'
import qs from 'qs'
import cloneDeep from 'lodash/cloneDeep'

import constantRouter, {
  notFoundRouter
} from './constantRouter'

import authorityRouter from './authorityRouter'


const routerNames = [];
/**
 * 获取路由表中所有路由名称
 */
function getAllRouterNames() {
  [...authorityRouter, notFoundRouter].forEach(({
    meta
  }) => {
    if (meta && meta.name) {
      routerNames.push(meta.name);
    }
  });
}


/**
 * 获取菜单授权
 * 
 * @param {*} to 跳转路由
 * @param {*} from 
 * @param {*} next 
 * @param {Object} param3 
 */
function loadMenuAuthority(to, from, next, {
  router,
  store
}) {
  store.dispatch('setRouteItemAsync').then(() => {
    //#region 遍历路由
    let menuNames = [],
      cloneRouterNames = {},
      routerUrlMeta = {};

    getRouterUrlMeta(menuNames, cloneRouterNames, routerUrlMeta, {
      router,
      store
    });

    store.commit('setRouteUrlMeta', routerUrlMeta);
    //#endregion

    const routers = getBindRouters(menuNames, cloneRouterNames, routerUrlMeta)

    router.addRoutes(routers);
    //继续执行路由
    next({
      ...to
    });
  }).catch((err) => {
    console.error(err);
    //如果报异常就直接404
    router.addRoutes([notFoundRouter])
  })
}

//#region 组装源数据
/**
 * 组装源数据
 * 
 * @param {Array<String>} menuNames 
 * @param {Object} cloneRouterNames 
 * @param {Object} routerUrlMeta 
 * @param {Object} param4
 */
function getRouterUrlMeta(menuNames, cloneRouterNames, routerUrlMeta, {
  router,
  store
}) {
  store.state.routeItem.forEach((item, index) => {
    (item.children || []).forEach((item, index) => {
      //获取所有菜单中的name
      menuNames.push(item.name);
      routerUrlMeta[item.name] = {
        name: item.name,
        title: item.title,
        href: item.href,
      };

      if (item.icon) {
        // 额外信息保存到RouteUrlMeta
        //备注, 里面包括icon, project信息
        const summary = JSON.parse(item.icon || '{}');
        routerUrlMeta[item.name] = {
          ...routerUrlMeta[item.name],
          project: summary.project,
          props: summary.props,
          key: summary.key,
          clone: summary.clone || ''
        }

        if (typeof summary.clone === 'string' && item.name !== summary.clone) {
          // 如果当前路由从其他路由拷贝
          let paths = cloneRouterNames[summary.clone] || [];
          paths.push(item.name);
          cloneRouterNames[summary.clone] = paths;
        }
      }
    });
  });

}
//#endregion

//#region 获取项目绑定路由
/**
 * 获取项目绑定路由
 * 
 * @param {Array} menuNames 
 * @param {Object} cloneRouterNames 
 * @param {Object} routerUrlMeta 
 */
function getBindRouters(menuNames, cloneRouterNames, routerUrlMeta) {
  let routers = [];
  authorityRouter.forEach((item, index) => {
    if (item.meta && item.meta.name) {
      let routerName = item.meta.name;

      // 正常菜单匹配到的路由
      if (menuNames.includes(routerName)) {
        if (item.children && item.children[0]) {
          let cloneItem = item;

          const firstChild = cloneItem.children[0],
            routerUrlItem = routerUrlMeta[item.meta.name];

          appendExtension(firstChild, routerUrlItem);
          routers.push(cloneItem);
        }
      }

      // 通过clone属性
      if (cloneRouterNames[routerName]) {
        cloneRouterNames[routerName].forEach(clonePath => {
          if (item.children && item.children[0]) {
            let cloneItem = cloneDeep(item);
            const firstChild = cloneItem.children[0],
              routerUrlItem = routerUrlMeta[clonePath];

            //#region 重新设置路由配置
            cloneItem.component = item.component;
            cloneItem.path = `/${clonePath}`;
            cloneItem.meta.name = clonePath;
            firstChild.name = clonePath;
            firstChild.component = item.children[0].component;
            //#endregion

            appendExtension(firstChild, routerUrlItem);

            //附加扩展信息key到router的meta
            Object.assign(firstChild.meta, {
              key: routerUrlItem.key || clonePath
            });
            routers.push(cloneItem);
          }
        });
      }
    }
  });

  // 最后添加notFound
  routers.push(notFoundRouter);
  return routers;
}
/**
 * 向路由中附加额外配置信息
 * 
 * @param {*} router 
 * @param {*} urlMetaItem 
 */
function appendExtension(router, urlMetaItem) {
  //扩展路由的props, 可可用于控制按钮的显示和隐藏
  if (urlMetaItem.props) {
    router.props = {
      ...router.props,
      ...urlMetaItem.props
    }
  }
  router.meta = {
    ...router.meta
  };
  //附加菜单的title到route的meta
  Object.assign(router.meta, {
    title: urlMetaItem.title
  });

  //附加扩展信息key到router的meta
  if (urlMetaItem.key) {
    Object.assign(router.meta, {
      key: urlMetaItem.key
    });
  }
}
//#endregion

/**
 * 正常路由跳转
 * 
 * @param {*} to 跳转路由
 * @param {*} from 
 * @param {*} next 
 * @param {Object} param3 
 */
function gotoRouter(to, from, next, {
  router,
  store
}) {
  //如果路由地址在当前项目中没有匹配到路由, 继续需找存储的第三方路由信息
  if (to.name === 'NoFound') {
    let path = to.path.replace(/\//g, ''),
      routeUrlMetaItem = store.state.routeUrlMeta[path];

    //如果维护了菜单
    if (routeUrlMetaItem) {
      if (routeUrlMetaItem.project &&
        routeUrlMetaItem.project !== store.state.project) {
        //第三方页面嵌入到iframe
        store.commit('isIframeOuter', true);
        let href = `${routeUrlMetaItem.href}?${qs.stringify(to.query)}` || `/${routeUrlMetaItem.project}/#${to.fullPath}`
        store.commit('setIframeOuterUrl', href);
        return next();
      }
    }
  }
  store.commit('isIframeOuter', false);
  next();
}


/**
 * 创建路由
 * 
 * @param {Object} param0 
 */
export default function createRouter({
  store,
  NProgress
}) {
  Vue.use(Router);

  const router = new Router({
    scrollBehavior: () => ({
      y: 100
    }),
    routes: constantRouter
  });

  //getAllRouterNames();

  if (false && process.env.NODE_ENV == 'development') {
    //开发环境
    store.dispatch('setRouteItemAsync').then(() => {
      router.addRoutes([...authorityRouter, notFoundRouter]);
    })
    router.beforeEach((to, from, next) => {
      NProgress.start();
      next();
    });

  } else {
    router.beforeEach((to, from, next) => {
      NProgress.start();
      //如果菜单没有加载加载菜单
      if (!store.state.routeDone) {
        loadMenuAuthority(to, from, next, {
          router,
          store
        });
      } else {
        //进行正常跳转
        gotoRouter(to, from, next, {
          router,
          store
        });
      }
    })
  };

  router.afterEach(() => {
    NProgress.done();
  });

  return router;
}
